using Engine;
using Engine.Audio;
using Engine.Media;
using Game;

namespace RuthlessConquest {
    public class SliderWidget : CanvasWidget {
        public CanvasWidget SliderCanvasWidget;

        public CanvasWidget LabelCanvasWidget;

        public Widget TabWidget;

        public LabelWidget LabelWidget;

        public float publicMinValue;

        public float publicMaxValue = 1f;

        public float publicGranularity = 0.1f;

        public float publicValue;

        public Vector2? DragStartPoint;

        public bool IsSliding { get; set; }

        public LayoutDirection LayoutDirection { get; set; }

        public float MinValue {
            get => publicMinValue;
            set {
                if (value != publicMinValue) {
                    publicMinValue = value;
                    MaxValue = MathUtils.Max(MinValue, MaxValue);
                    Value = MathUtils.Clamp(Value, MinValue, MaxValue);
                }
            }
        }

        public float MaxValue {
            get => publicMaxValue;
            set {
                if (value != publicMaxValue) {
                    publicMaxValue = value;
                    MinValue = MathUtils.Min(MinValue, MaxValue);
                    Value = MathUtils.Clamp(Value, MinValue, MaxValue);
                }
            }
        }

        public float Value {
            get => publicValue;
            set {
                if (publicGranularity > 0f) {
                    publicValue = MathUtils.Round(MathUtils.Clamp(value, MinValue, MaxValue) / publicGranularity) * publicGranularity;
                }
                else {
                    publicValue = MathUtils.Clamp(value, MinValue, MaxValue);
                }
            }
        }

        public float Granularity {
            get => publicGranularity;
            set => publicGranularity = MathUtils.Max(value, 0f);
        }

        public string Text {
            get => LabelWidget.Text;
            set => LabelWidget.Text = value;
        }

        public BitmapFont Font {
            get => LabelWidget.Font;
            set => LabelWidget.Font = value;
        }

        public SoundBuffer Sound { get; set; }

        public bool IsLabelVisible {
            get => LabelCanvasWidget.IsVisible;
            set => LabelCanvasWidget.IsVisible = value;
        }

        public float LabelWidth {
            get => LabelCanvasWidget.Size.X;
            set => LabelCanvasWidget.Size = new Vector2(value, LabelCanvasWidget.Size.Y);
        }

        public SliderWidget() {
            Sound = Sounds.Slider;
            StackPanelWidget panel1 = new() { Direction = LayoutDirection.Horizontal, IsHitTestVisible = false, Margin = new Vector2(0f, 10f) };
            SliderCanvasWidget = new CanvasWidget {
                Children = {
                    new RectangleWidget {
                        Size = new Vector2(float.PositiveInfinity, 6f),
                        OutlineColor = Color.Transparent,
                        FillColor = Colors.HighDim,
                        Margin = new Vector2(10f, 0f),
                        VerticalAlignment = WidgetAlignment.Center
                    }
                }
            };
            TabWidget = new BevelledRectangleWidget { Size = new Vector2(30f, 45f), IsHitTestVisible = true, BevelSize = 2f };
            SliderCanvasWidget.Children.Add(TabWidget);
            panel1.Children.Add(SliderCanvasWidget);
            LabelCanvasWidget = new CanvasWidget { Size = new Vector2(100f, -1f) };
            LabelWidget = new LabelWidget { HorizontalAlignment = WidgetAlignment.Far, VerticalAlignment = WidgetAlignment.Center };
            LabelCanvasWidget.Children.Add(LabelWidget);
            panel1.Children.Add(LabelCanvasWidget);
            Children.Add(panel1);
        }

        public override void MeasureOverride(Vector2 parentAvailableSize) {
            base.MeasureOverride(parentAvailableSize);
            IsDrawRequired = true;
        }

        public override void ArrangeOverride() {
            base.ArrangeOverride();
            float num = LayoutDirection == LayoutDirection.Horizontal ? SliderCanvasWidget.ActualSize.X : SliderCanvasWidget.ActualSize.Y;
            float num2 = LayoutDirection == LayoutDirection.Horizontal ? TabWidget.ActualSize.X : TabWidget.ActualSize.Y;
            float num3 = MaxValue > MinValue ? (Value - MinValue) / (MaxValue - MinValue) : 0f;
            if (LayoutDirection == LayoutDirection.Horizontal) {
                Vector2 zero = Vector2.Zero;
                zero.X = num3 * (num - num2);
                zero.Y = MathUtils.Max((SliderCanvasWidget.ActualSize.Y - TabWidget.ActualSize.Y) / 2f, 0f);
                SliderCanvasWidget.SetWidgetPosition(TabWidget, zero);
            }
            else {
                Vector2 zero2 = Vector2.Zero;
                zero2.X = MathUtils.Max(SliderCanvasWidget.ActualSize.X - TabWidget.ActualSize.X, 0f) / 2f;
                zero2.Y = num3 * (num - num2);
                SliderCanvasWidget.SetWidgetPosition(TabWidget, zero2);
            }
            base.ArrangeOverride();
        }

        public override void Update() {
            float num = LayoutDirection == LayoutDirection.Horizontal ? SliderCanvasWidget.ActualSize.X : SliderCanvasWidget.ActualSize.Y;
            float num2 = LayoutDirection == LayoutDirection.Horizontal ? TabWidget.ActualSize.X : TabWidget.ActualSize.Y;
            if (Input.Tap.HasValue
                && HitTestGlobal(Input.Tap.Value) == TabWidget) {
                DragStartPoint = ScreenToWidget(Input.Press.Value);
            }
            if (Input.Press.HasValue) {
                if (DragStartPoint.HasValue) {
                    Vector2 vector = ScreenToWidget(Input.Press.Value);
                    float value = Value;
                    if (LayoutDirection == LayoutDirection.Horizontal) {
                        float f = (vector.X - num2 / 2f) / (num - num2);
                        Value = MathUtils.Lerp(MinValue, MaxValue, f);
                    }
                    else {
                        float f2 = (vector.Y - num2 / 2f) / (num - num2);
                        Value = MathUtils.Lerp(MinValue, MaxValue, f2);
                    }
                    if (Value != value
                        && publicGranularity > 0f
                        && Sound != null) {
                        AudioManager.PlaySound(Sound, false);
                    }
                }
            }
            else {
                DragStartPoint = null;
            }
            IsSliding = DragStartPoint.HasValue && IsEnabledGlobal && IsVisibleGlobal;
            if (DragStartPoint.HasValue) {
                Input.Clear();
            }
        }
    }
}